package sg.edu.nus.iss.vmcs.customer;

import java.awt.Frame;

import sg.edu.nus.iss.vmcs.machinery.MachineryController;
import sg.edu.nus.iss.vmcs.maintenance.AccessManager;
import sg.edu.nus.iss.vmcs.maintenance.MaintenancePanel;
//import sg.edu.nus.iss.vmcs.store.DrinksBrand;
//import sg.edu.nus.iss.vmcs.store.DrinksStoreItem;
//import sg.edu.nus.iss.vmcs.store.PropertyLoader;
import sg.edu.nus.iss.vmcs.store.DrinksBrand;
import sg.edu.nus.iss.vmcs.store.DrinksStore;
import sg.edu.nus.iss.vmcs.store.DrinksStoreItem;
import sg.edu.nus.iss.vmcs.store.Store;
import sg.edu.nus.iss.vmcs.store.StoreController;
import sg.edu.nus.iss.vmcs.store.StoreItem;
import sg.edu.nus.iss.vmcs.store.StoreObject;
import sg.edu.nus.iss.vmcs.system.MainController;
import sg.edu.nus.iss.vmcs.system.SimulationController;
import sg.edu.nus.iss.vmcs.system.SimulatorControlPanel;
import sg.edu.nus.iss.vmcs.util.VMCSException;

public class TransactionController {
	
	private Boolean changeGiven;
	private Boolean drinkDispensed;
	private Integer price;
	private Integer selection;
	
	private MainController mCtrl;
	private DispenseController  dispenseCtrl ;
	private ChangeGiver 	  changeGiver;
	private CoinReceiver   coinReceiver;
	private CustomerPanel cPanel;

	//private PropertyLoader drinksLoader;

	public TransactionController(MainController mctrl) {
		mCtrl = mctrl;
		
		this.dispenseCtrl=new DispenseController(this);
		this.changeGiver=new ChangeGiver(this);
		this.coinReceiver=new CoinReceiver(this);
		
		selection=-1;
	}

	public MainController getMainController() {
		return mCtrl;
	}
	
	public DispenseController getDispenseController() {
		return dispenseCtrl;
	}
	
	public ChangeGiver getChangeGiver() {
		return changeGiver;
	}
	
	public CoinReceiver getCoinReceiver() {
		return coinReceiver;
	}
	
	public CustomerPanel getCustomerPanel(){
		return cPanel;
	}
		
	public void startTransaction(Integer identifier){
		selection=identifier;
		StoreController storeCtrl=mCtrl.getStoreController();
		DrinksStore ds=(DrinksStore) storeCtrl.getStore(Store.DRINK);
		DrinksStoreItem dstoreItem=(DrinksStoreItem) ds.getStoreItem(identifier);
		DrinksBrand dBrand=(DrinksBrand) dstoreItem.getContent();
		this.price=dBrand.getPrice();
		changeGiver.resetChange();		
		dispenseCtrl.resetCan();
		changeGiver.displayChangeStatus();
		dispenseCtrl.allowSelection(false);
		coinReceiver.startReceive();
	}
	
	public void processMoneyReceived(Integer total) {
		
		if(total>=this.price){
			this.completeTransaction();
		}
		else{
			this.coinReceiver.continueReceive();
		}
	}
	
	public void completeTransaction(){
		
		
		//Dispense Drink
		try {
			drinkDispensed=dispenseCtrl.dispenseDrink(this.selection); 			
		}
		catch (VMCSException v){
			drinkDispensed=false;
			System.out.println(v.getMessage());
		}		
		if(!drinkDispensed){
			this.terminateFault();
			return;
		}
		
		//Give Change
		Integer amount_change=coinReceiver.getTotalInserted()-this.price;
		if(amount_change>0){
			changeGiven=changeGiver.giveChange(amount_change);
			if(!changeGiven){
				this.terminateFault();
				return;
			}
		}
		
		
		//Store Cash
		Boolean cashStored;
		cashStored=coinReceiver.storeCash();
		if(!cashStored){			
			this.terminateFault();
			return;
		}
		
		//Update Customer Panel to allow drink selection
		dispenseCtrl.allowSelection(true);	
		
		selection=-1;
	}
	
	public void terminateFault(){
		this.dispenseCtrl.allowSelection(false);
		
		if(!this.changeGiven) this.coinReceiver.storeCash();
		if(!this.drinkDispensed) this.coinReceiver.refundCash();
		
		selection=-1;
	}
	
	public void terminateTransaction(){
				
		if(this.selection>=0)
		{			
			coinReceiver.stopReceive();
			coinReceiver.refundCash();
		}
		else{			
			dispenseCtrl.allowSelection(false);
		}
		
		selection=-1;		
	}
	
	public void cancelTransaction(){
		if(selection>=0){
			this.coinReceiver.stopReceive();
			this.coinReceiver.refundCash();
			this.dispenseCtrl.allowSelection(true);
		}
		
		selection=-1;
	}
	
	public void closeDown(){
		if(cPanel == null)//included by vinod
			return;
	cPanel.dispose();
	mCtrl.getSimulatorControlPanel().setActive(SimulatorControlPanel.ACT_CUSTOMER, true);//included by vinod
	}
	
	public void displayCustomerPanel(){
		SimulatorControlPanel scp = mCtrl.getSimulatorControlPanel();
		if (cPanel == null)
			cPanel = new CustomerPanel((Frame) scp, this);
		cPanel.display();
		this.getDispenseController().updateDrinkPanel();
		this.getDispenseController().allowSelection(true);
		this.getChangeGiver().displayChangeStatus();
		this.getCoinReceiver().setActive(false);
		//changes outside design vinod
		this.getCustomerPanel().getInvalidCoinDisplay().setState(false);
		this.getCustomerPanel().getNoChangeDisplay().setState(false);
	}
	
	public void refreshCustomerPanel(){
		
		//Update Drink Panel
		dispenseCtrl.updateDrinkPanel();		
		//
		mCtrl.getSimulationController().getSimulatorControlPanel().setActive(SimulatorControlPanel.ACT_CUSTOMER,true);
		
		//Allow Customer Transaction
		this.dispenseCtrl.allowSelection(true);
		
		//Display Change Status
		changeGiver.displayChangeStatus();
	}
	

}
